﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace November {
    class DirectoryModel : INovModel {
        private List<String> FileNameList { get; set; }
        private Int32 Index { get; set; }
        private SortMode SortMode { get; set; }

        public DirectoryModel(String directoryName) {
            FileNameList = Directory.EnumerateFiles(directoryName).Where(Utility.ImageFilter).ToList();
            Index = 0;
            SortBy(SortMode.Name);
        }

        public DirectoryModel(String directoryName, String fileName) {
            FileNameList = Directory.EnumerateFiles(directoryName).Where(Utility.ImageFilter).ToList();
            Index = FileNameList.IndexOf(fileName);
            SortBy(SortMode.Name);
        }

        public Image GetImage() {
            return Image.FromFile(GetImageName());
        }

        public String GetImageName() {
            return FileNameList[Index];
        }

        public Int32 GetImageIndex() {
            return Index + 1;
        }

        public Int32 GetImageCount() {
            return FileNameList.Count;
        }

        public Boolean FirstImage() {
            return Index != (Index = 0);
        }

        public Boolean EarlierImage() {
            if (SortMode != SortMode.Date) return false;

            Func<String, DateTime> map = x => File.GetCreationTime(x).Date;
            IIndexed<DateTime> list = new MappedList<String, DateTime>(FileNameList, map);
            return Index != (Index = Utility.FindEarlier(list, Index));
        }

        public Boolean PreviousImage() {
            Index = (Index + GetImageCount() - 1) % GetImageCount();
            return GetImageCount() != 1;
        }

        public Boolean NextImage() {
            Index = (Index + 1) % GetImageCount();
            return GetImageCount() != 1;
        }

        public Boolean LaterImage() {
            if (SortMode != SortMode.Date) return false;

            Func<String, DateTime> map = x => File.GetCreationTime(x).Date;
            IIndexed<DateTime> list = new MappedList<String, DateTime>(FileNameList, map);
            return Index != (Index = Utility.FindLater(list, Index));
        }

        public Boolean LastImage() {
            return Index != (Index = GetImageCount() - 1);
        }

        public Boolean SortBy(SortMode sortMode) {
            String current = GetImageName();
            switch (sortMode) {
                case SortMode.Name:
                    FileNameList.Sort(new AlphaNumericComparer());
                    break;
                case SortMode.Date:
                    FileNameList.Sort(new DateCreatedComparer());
                    break;
                case SortMode.Random:
                    Random random = new Random();
                    for (int i = GetImageCount() - 1; i >= 0; i--) {
                        int j = random.Next(i + 1);
                        String temp = FileNameList[i];
                        FileNameList[i] = FileNameList[j];
                        FileNameList[j] = temp;
                    }
                    break;
            }
            Index = FileNameList.IndexOf(current);
            SortMode = sortMode;
            return true;
        }
    }
}
